﻿# define  _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;


//int main()
//{
//	//p *p b c皆为左值
//	int *p = new int(0);
//	cout << &p << endl;
//	cout << &(*p) << endl;
//
//	int b = 1;
//	cout << &b << endl;
//
//	const int c = 2;
//	cout << &c << endl;
//	return 0;
//}


////func1()函数的返回值为左值
//int& func1()
//{
//	static int x = 0;
//	return x;
//}

////func2()函数的返回值为右值
//int func2()
//{
//	static int x = 0;
//	return x;
//}
//int main()
//{ 
//	cout << &func2() << endl;
//	return 0;
//}

//int main()
//{
//	double x = 1.1, y = 2.2;
//
//	//字面量的生命周期仅限于它所在的表达式,所以字面量可以被视为临时对象
//	10;
//	//cout << &(10) << endl;(×)
//
//	//生成临时的double类型的对象存储表达式x+y计算所得出的结果
//	x + y;
//	//cout << &(x + y) << endl;(×)
//	return 0;
//}

//int main()
//{
//	// 以下的p、b、c、*p都是左值
//	int* p = new int(0);
//	int b = 1;
//	const int c = 2;
//	// 以下几个是对上面左值的左值引用
//	int*& rp = p;
//	int& rb = b;
//	const int& rc = c;
//	int& pvalue = *p;
//
//	return 0;
//}
//int main()
//{
//	double x = 1.1, y = 2.2;
//	// 以下几个都是常见的右值
//	10;
//	x + y;
//	fmin(x, y);
//
//	// 以下几个都是对右值的右值引用
//	int&& rr1 = 10;
//	double&& rr2 = x + y;
//	double&& rr3 = fmin(x, y);
//	return 0;
//}
//
//int main()
//{
//	int x = 0;
//
//	int& r = x;
//
//	int&& rr= 10;
//	return 0;
//}

//int main()
//{
//	// 左值引用只能引用左值，不能引用右值
//	int a = 10;
//	int& ra1 = a;// ra1为a的别名
//	//int& ra2 = 10;   // 编译失败，因为10是右值
//
//	// const左值引用既可引用左值，也可引用右值
//	const int& ra3 = 10;
//	const int& ra4 = a;
//	return 0;
//}
//
//int main()
//{
//	// 右值引用只能右值，不能引用左值。
//	int&& r1 = 10;
//
//	// error C2440: “初始化”: 无法从“int”转换为“int &&”
//	// message : 无法将左值绑定到右值引用
//	int a = 10;
//	int&& r2 = a;
//
//	// 右值引用可以引用move以后的左值
//	int&& r3 = std::move(a);
//	return 0;
//}

//编译器优化行为分析
class A
{
public:
	//构造函数
	A(int a = 0)
		:_a(a)
	{
		cout << "调用构造函数" << endl;
	}
	//拷贝构造函数
	A(const A& aa)
		:_a(aa._a)
	{
		cout << "调用拷贝构造函数" << endl;
	}
	//赋值运算符重载
	A& operator=(const A& aa)
	{
		if (this != &aa)
		{
			_a = aa._a;
		}
		cout << "调用赋值运算符重载" << endl;
		return *this;
	}
	//析构函数
	~A()
	{
		cout << "调用析构函数" << endl;
	}
private:
	int _a;
};

void test1()
{
	//10---内置类型  aa1---自定义类型  (隐式类型转换)
	// 编译器未优化:  10构造临时对象，临时对象拷贝构造aa1
	// 编译器优化:    直接调用构造函数(构造与拷贝构造合二为一)
	A aa1 = 10;
}

void test2()
{
	A aa1;//调用构造函数初始化对象aa1

	aa1 = 10;//10---内置类型 aa1---自定义类型
	//产生临时对象,10构造临时对象，临时对象调用赋值运算符重载拷贝赋值aa1
	//编译器无法优化
}

A func()
{
	A aa;
	return aa;
}
void  test3()
{
	//编译器优化
	//编译器未优化: 先用func()函数的返回对象拷贝构造匿名对象,再用匿名对象拷贝构造aa1
	//编译器优化: 直接调用一次拷贝构造函数(两次拷贝构造函数合二为一)
	// case 1：
	//A aa1 = func();

	// case 2:
	//aa1已经产生,编译器无法优化，先用func()函数的返回对象拷贝构造匿名对象然后调用赋值运算符重载
	A aa1;
	aa1 = func();

}
void test4()
{
    const A& aa1 = 10;
}
int main()
{
	//test1();
	//test2();
	//test3();
	test4();
	return 0;
}







